package com.dmw.filter;

import com.dmw.common.contant.JwtClaimsConstant;
import com.dmw.common.contant.StatusConstant;
import com.dmw.common.properties.JwtProperties;
import com.dmw.common.util.JwtUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@Component
@Slf4j
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JwtProperties jwtProperties;

    // 公开接口
    private static final List<String> OPEN_PATHS = Arrays.asList(
            "/user/login",
            "/user/register" ,
            "/v3/api-docs/**",
            "/swagger-ui/**"
    );

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {

        String path = request.getRequestURI();
        log.info("处理请求: {}", path);
        // 跳过公开路径的JWT验证
        if (OPEN_PATHS.stream().anyMatch(path::startsWith)) {
            log.info("跳过公开路径: {}", path);
            chain.doFilter(request, response);
            return;
        }

        log.info("JWT验证开始: {}", request.getRequestURI());

        // 1. 从请求头中获取Token
        String tokenHeader = request.getHeader(jwtProperties.getAdminTokenName());

        // 2. 检查Token是否存在且格式正确
        if (tokenHeader == null || !tokenHeader.startsWith("Bearer ")) {
            tokenHeader = request.getHeader(jwtProperties.getUserTokenName());
            if (tokenHeader == null || !tokenHeader.startsWith("Bearer ")) {
                chain.doFilter(request, response); // 无Token，继续过滤链
                log.info("未发现token");
                return;
            }
        }

        // 3. 提取Token
        String token = tokenHeader.substring(7).trim();

        try {
            // 4. 根据Token来源选择对应的密钥
            String secretKey = jwtProperties.getAdminTokenName().equals(request.getHeader(jwtProperties.getAdminTokenName()))
                    ? jwtProperties.getAdminSecretKey()
                    : jwtProperties.getUserSecretKey();

            // 5. 解析JWT并验证签名和有效期
            Claims claims = JwtUtil.parseJWT(secretKey, token);

            // 6. 从Claims中提取用户信息
            Long userId = claims.get(JwtClaimsConstant.USER_ID, Long.class);
            String username = claims.get(JwtClaimsConstant.USERNAME, String.class);
            String role = claims.get(JwtClaimsConstant.ROLE, String.class);


            // 8. 创建认证对象
            UsernamePasswordAuthenticationToken authentication =
                    new UsernamePasswordAuthenticationToken(
                            username,  // 仅存储用户名（或用户ID）
                            null,
                            Collections.singletonList(new SimpleGrantedAuthority("ROLE_" + role))
                    );

            // 9. 设置认证信息到SecurityContext
            SecurityContextHolder.getContext().setAuthentication(authentication);
            log.info("JWT验证成功: {}", username);

        } catch (Exception e) {
            // Token验证失败
            log.error("JWT验证失败: {}", e.getMessage());
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return;
        }

        // 继续执行过滤链
        chain.doFilter(request, response);
    }
}